package j3dscene;

import j3dscene.models.Drums;
import j3dscene.models.RearWall;
import j3dscene.models.Ground;
import j3dscene.models.Poster;
import j3dscene.models.SideWall;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;
import javax.media.j3d.*;
import javax.swing.JFrame;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

/**
 * This class contains all visible objects, transforms them and puts them
 * on the Simple Universe.
 *
 * @author Dominik K.
 * @author Steffen G.
 */
public class Screen {

    /**
     * Canvas of Java3D
     * @see Canvas3D
     */
    private static Canvas3D canvas;
    
    /**
     * Contains every branch- or transformgroup.
     */
    private static BranchGroup objectRoot;
    
    /**
     * Simple Universe of Java3D
     * @see SimpleUniverse
     */
    private static SimpleUniverse simpUniv;
    
    /**
     * Creates all objects and light, transforms them and adds 
     * them the Universe.
     * 
     * Also initialise animation and picking.
     * 
     */
    public static void init() {
        /*
         * Basic configuration
         */
        
        canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
        simpUniv = new SimpleUniverse(canvas);
        //getSimpUniv().getViewingPlatform().setNominalViewingTransform();
        ViewingPlatform vp = simpUniv.getViewingPlatform();
        TransformGroup steerTG = vp.getViewPlatformTransform( );
        Transform3D t3d = new Transform3D( );
        steerTG.getTransform(t3d);
        t3d.lookAt( new Point3d(0,1,2), new Point3d(0,0.2,0), new Vector3d(0,1,0));
        t3d.invert( );
        steerTG.setTransform(t3d);
        objectRoot = new BranchGroup();
        getObjectRoot().setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
        getObjectRoot().setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
        
        /*
         * Loading VRML object (drums)
         */
        java.net.URL url = ClassLoader.getSystemResource("files/DrumsFinalV5.wrl");
        Drums drums = new Drums(url);
        
        /*
         * Creating other objects (walls, etc.)
         */
        SceneBackground background = new SceneBackground();
        Ground ground = new Ground();
        SideWall wallLeft = new SideWall();
        SideWall wallRight = new SideWall();
        RearWall rearWall = new RearWall();
        Poster poster1 = new Poster("files/pPoster.jpg");
        Poster poster2 = new Poster("files/gPoster.jpg");
        Poster poster3 = new Poster("files/tPoster.jpg");
        
        /*
         * Transforming objects
         */
        //ground
        Transform3D transGround = new Transform3D();
        transGround.setTranslation(new Vector3f(0.0f, -0.02f, 0.0f));
        TransformGroup transformedGround = 
                new TransformGroup(transGround);
        transformedGround.addChild(ground);
        
        //wallLeft
        Transform3D transWallLeft = new Transform3D();
        transWallLeft.setTranslation(new Vector3f(-0.9f + 0.02f, 0.3f, 0.0f));
        TransformGroup transformedWandLinks = 
                new TransformGroup(transWallLeft);
        transformedWandLinks.addChild(wallLeft);

        //wallRight
        Transform3D transWandRechts = new Transform3D();
        transWandRechts.setTranslation(new Vector3f(0.9f - 0.02f, 0.3f, 0.0f));
        TransformGroup transformedWandRechts = 
                new TransformGroup(transWandRechts);
        transformedWandRechts.addChild(wallRight);
        
        //rearWall
        Transform3D transRueckWand = new Transform3D();
        transRueckWand.setTranslation(new Vector3f(0.0f, 0.3f, -0.9f + 0.02f));
        TransformGroup transformedRueckWand =
                new TransformGroup(transRueckWand);
        transformedRueckWand.addChild(rearWall);
  

        //poster1
        Transform3D transPoster1 = new Transform3D();
        transPoster1.setTranslation(new Vector3f(-0.1f, 0.35f, -0.875f));
        transPoster1.setRotation(new AxisAngle4d(0f, 0f, 1f, Math.toRadians(11)));
        TransformGroup transformedPoster1 = new TransformGroup(transPoster1);
        transformedPoster1.addChild(poster1);

        //poster2
        Transform3D transPoster2A = new Transform3D();
        transPoster2A.setTranslation(new Vector3f(-0.875f, 0.31f, -0.07f));
        transPoster2A.setRotation(new AxisAngle4d(0f, 1f, 0f, Math.toRadians(90)));
        Transform3D transPoster2B = new Transform3D();
        transPoster2B.setRotation(new AxisAngle4d(0f, 0f, 1f, Math.toRadians(7)));
        Transform3D transPoster2 = new Transform3D();
        transPoster2.mul(transPoster2A, transPoster2B);
        TransformGroup transformedPoster2 = new TransformGroup(transPoster2);
        transformedPoster2.addChild(poster2);

        //poster3
        Transform3D transPoster3A = new Transform3D();
        transPoster3A.setTranslation(new Vector3f(0.875f, 0.322f, 0.3f));
        transPoster3A.setRotation(new AxisAngle4d(0f, 1f, 0f, Math.toRadians(270)));
        Transform3D transPoster3B = new Transform3D();
        transPoster3B.setRotation(new AxisAngle4d(0f, 0f, 1f, Math.toRadians(-14)));
        Transform3D transPoster3 = new Transform3D();
        transPoster3.mul(transPoster3A, transPoster3B);
        TransformGroup transformedPoster3 = new TransformGroup(transPoster3);
        transformedPoster3.addChild(poster3);
        
        /*
         * Adding elements to objectRoot
         */
        getObjectRoot().addChild(drums.getSceneGroup());
        getObjectRoot().addChild(transformedGround);
        getObjectRoot().addChild(transformedWandLinks);
        getObjectRoot().addChild(transformedWandRechts);
        getObjectRoot().addChild(transformedRueckWand);
        getObjectRoot().addChild(transformedPoster1);
        getObjectRoot().addChild(transformedPoster2);
        getObjectRoot().addChild(transformedPoster3);
        
        /*
         * Initialising picking
         */
        Picker pick = new Picker(
                getCanvas(), getObjectRoot(), new BoundingSphere());
        getObjectRoot().addChild(pick);
        
        /*
         * Initialising animation
         */
        Animator.init(drums);
        
        /*
         * Adding light and objectRoot to SimpleUniverse
         */
        getSimpUniv().addBranchGraph(getObjectRoot());
        getSimpUniv().addBranchGraph(background);
        getSimpUniv().addBranchGraph(new Light());
        
        /*
         * Orbit Behaviour
         */
        OrbitBehavior ob = new OrbitBehavior(getCanvas(),OrbitBehavior.REVERSE_ROTATE);
        ob.setSchedulingBounds(new BoundingSphere(
                new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE));
        getSimpUniv().getViewingPlatform().setViewPlatformBehavior(ob);
        
        
    }

    /**
     * @return the canvas
     */
    public static Canvas3D getCanvas() {
        return canvas;
    }

    /**
     * @return the objectRoot
     */
    public static BranchGroup getObjectRoot() {
        return objectRoot;
    }

    /**
     * @return the simpUniv
     */
    public static SimpleUniverse getSimpUniv() {
        return simpUniv;
    }
}
